<--- %%NOBANNER%% --> poiss_ss.sas
 BackForward

/*------------------<--  Start of Description -->--------------------\
| Estimate sample size for Poisson Regression.                       |
| Useful for incidence rate sample size calculations.To test for     |
| trends in incidence rates(Y) over calendar time(X), we often model:|
|     log(Y)=a + Xb + 1*offset,                                      |
|           where Y is Poisson, X is the calendar year               |
|           and the offset is typically log(population)              |
| The macro allows various choices for the distribtuion of X         |
| including uniform, normal and Bernoulli. The uniform assumption    |
| seems appropriate when X is calendar year. In Olmsted County       |
| incidence studies, the only covariates we typically have for both  |
| numerator and denominator are calendar year, gender and age.       |
|--------------------<--  End of Description -->---------------------|
|--------------------------------------------------------------------|
|--------------<--  Start of Files or Arguments Needed -->-----------|
| Arguments:                                                         |
|    alpha=type 1 error, default is .05 .                            |
|    sides=1 or 2 for one or two sided test,default is 2.            |
|    power=desired statistical power as a fraction.                  |
|          Default is .80.                                           |
|    rrlow,rrhi,rrinc=defines range of true rate ratios to evaluate. |
|          RRLOW is the minimum, RRHI the maximum and RRINC the      |
|          increment.                                                |
|          Defaults are 0.5, 2.0 and 0.1.                            |
|    uniform=Y if you wish to print output ONLY for uniform X.       |
|          Default is to print results for all distributions, with   |
|          more detail for the case where X is uniform.              |
|    Output: Table of number of events required to detect possible   |
|          true rate ratios. Addition details for uniform X.         |
|----------------<--  Start of Example and Usage -->-----------------|
| Example: %poiss_ss(sides=1,power=.95,rrlow=1.1,rrhi=2.0,rrinc=.02);|
| Usage:   %poiss_ss(alpha=.05,sides=2,power=.80, rrlow=.5,          |
|                    rrhi=2.0,rrinc=0.1,uniform=N);                  |
| Reference: Signorini, Biometrika 1991, 78, 2, pp. 446-50.          |
\-------------------<--  End of Example and Usage -->---------------*/
 %macro poiss_ss(alpha=.05,sides=2,power=.80,
                 rrlow=.5,rrhi=2.0,rrinc=0.1,uniform=N);
/*--------------------------------------------\
| Author:  E. Bergstralh;                     |
| Created: 12/3/96                            |
| Purpose: Estimate sample size for Poisson   |
|          Regression;                        |
\--------------------------------------------*/
 Data one;
  sides=&sides;
  alpha=α
  power=&power;
  zalpha=(PROBIT(1-ALPHA))*(SIDES=1) +
     (   PROBIT(1-ALPHA/2))*(SIDES=2);
  zbeta=probit(power);

  do rr=&rrlow to &rrhi by &rrinc;           **rr=rate ratio;

   b=log(rr);

   **** Variance of b for some common distributions;
   sd_bu=sqrt( ( sqrt(3)*(b**3) * (sinh(sqrt(3)*b) ) ) /
        ( (sinh(sqrt(3)*b))**2 - 3*(b**2) ) ); **uniform x;
   sd_bn= sqrt( exp( -.5*(b**2) ) );         **normal x;
   sd_bbp1=sqrt( 1/(.1*exp(b)) + 1/(1-.1));  **x is bernoulli .1;
   sd_bbp5=sqrt( 1/(.5*exp(b)) + 1/(1-.5));  **x is bernoulli .5;
   sd_bbp9=sqrt( 1/(.9*exp(b)) + 1/(1-.9));  **x is bernoulli .9;

   **** Number of events required, given power,alpha,sides,distn;
   evt_uni=(zalpha/1 + zbeta*sd_bu )**2 / b**2;
   evt_nml=(zalpha/1 + zbeta*sd_bn )**2 / b**2;
   evt_bp1=(zalpha/sqrt(.1*.9) + zbeta*sd_bbp1 )**2 / b**2;
   evt_bp5=(zalpha/sqrt(.5*.5) + zbeta*sd_bbp5 )**2 / b**2;
   evt_bp9=(zalpha/sqrt(.9*.1) + zbeta*sd_bbp9 )**2 / b**2;

   **** Additional Interpretations of Rate Ratio for Uniform X;
   rr_SD=rr;                  **Rename to emphasize 1SD shift;
   rr_rng=rr_sd**3.464;       ** 3.464 times SD=range..unif. X;
   rr1_10=exp( 3.464*b/10 );  **annual change for 10y study;
   rr1_20=exp( 3.464*b/20 );  **annual change for 20y study;
   rr1_30=exp( 3.464*b/30 );  **annual change for 30y study;
   evt_uni2=evt_uni;

   format rr_sd  rr_rng 8.2 rr1_10--rr1_30 8.3
   evt_uni evt_uni2 evt_nml evt_bp1 evt_bp5 evt_bp9 8.1;
   output;
  end;

  Label rr_rng="Rate ratio*over range of x"
        rr1_10="Annual rate ratio*10 year study"
        rr1_20="Annual rate ratio*20 year study"
        rr1_30="Annual rate ratio*30 year study"
        evt_uni="Total events needed*to detect rate ratio"
        evt_uni2="Events needed*X uniform*1 SD shift"
        evt_nml="Events needed*X normal*1 SD shift"
        evt_bp1="Events needed*X Bernoulli(.1)*X=0 vs X=1"
        evt_bp5="Events needed*X Bernoulli(.5)*X=0 vs X=1"
        evt_bp9="Events needed*X Bernoulli(.9)*X=0 vs X=1" ;

 footnote"POISS_SS macro: Poisson Regression Sample Size";
 footnote2"alpha=&alpha sides=&sides power=&power";
 footnote3"Reference: Signorini, Biometrika(1991), 78, 2, pp. 446-50.";

 %if %upcase(&uniform)^=Y %then %do;
title4"Dep. var.(Y) is Poisson: Tabled values are numbers of eve
nts(Y>0) needed to detect given rate ratios";
title5"for various covariate(X) distns and shifts in X";
proc print split='*';  id rr_sd;
 var evt_nml evt_uni2 evt_bp1 evt_bp5 evt_bp9;
 label rr_sd="Rate ratio";
  run;
 %end;

title4"Dep. var.(Y) is Poisson: Tabled values are numbers of eve
nts(Y>0) needed to detect given rate ratios.";
title5"Rate Ratio Interpretations for UNIFORM X(e.g. calendar year).";
proc print split='*'; id rr_sd;
   var rr_rng rr1_10 rr1_20 rr1_30 evt_uni;
   label rr_sd="Rate ratio per*1 SD change in x" ;
run;
footnote;
run;
%mend;